import 'package:flutter/material.dart';

class AnimatedSwitcherCounterRoute extends StatefulWidget {
  const AnimatedSwitcherCounterRoute({Key key}) : super(key: key);
  @override
  _AnimatedSwitcherCounterRouteState createState() =>
      new _AnimatedSwitcherCounterRouteState();
}

class _AnimatedSwitcherCounterRouteState
    extends State<AnimatedSwitcherCounterRoute> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            AnimatedSwitcher(
                duration: const Duration(milliseconds: 500),
                //新数字会逐渐缩小至隐藏
                // transitionBuilder: (Widget child, Animation<double> animation) {
                //   return ScaleTransition(child: child, scale: animation);
                // },
                //路由进场切换的动画
                // transitionBuilder: (Widget child, Animation<double> animation) {
                //   var tween =
                //       Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0));
                //   return MySliderTransition(
                //       position: tween.animate(animation), child: child);
                // },
                //实现各种“滑动出入动画”
                transitionBuilder: (Widget child, Animation<double> animation) {
                  var tween =
                      Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0));
                  return SliderTransitionX(
                    position: animation,
                    child: child,
                    direction: AxisDirection.up,
                  );
                },
                child: Text(
                  '$_count',
                  //显式指定key，不同的key会被认为是不同的Text，这样才能执行动画
                  key: ValueKey<int>(_count),
                  style: Theme.of(context).textTheme.display1,
                )),
            RaisedButton(
                child: const Text(
                  '+1',
                ),
                onPressed: () {
                  setState(() {
                    _count += 1;
                  });
                })
          ]),
    );
  }
}

class MySliderTransition extends AnimatedWidget {
  MySliderTransition(
      {Key key,
      @required Animation<Offset> position,
      this.transformHitTests = true,
      this.child})
      : assert(position != null),
        super(key: key, listenable: position);

  Animation<Offset> get position => listenable;
  final bool transformHitTests;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Offset offset = position.value;
//动画反向执行时，调整x偏移，实现从左滑出隐藏
    if (position.status == AnimationStatus.reverse) {
      offset = Offset(-offset.dx, offset.dy);
    }

    return FractionalTranslation(
        translation: offset,
        transformHitTests: transformHitTests,
        child: child);
  }
}

class SliderTransitionX extends AnimatedWidget {
  SliderTransitionX(
      {Key key,
      @required Animation<double> position,
      this.transformHitTests = true,
      this.direction = AxisDirection.down,
      this.child})
      : assert(position != null),
        super(key: key, listenable: position) {
    //偏移在内部处理
    switch (direction) {
      case AxisDirection.up:
        _tween = Tween(begin: Offset(0, 1), end: Offset(0, 0));
        break;

      case AxisDirection.right:
        _tween = Tween(begin: Offset(-1, 0), end: Offset(0, 0));
        break;

      case AxisDirection.down:
        _tween = Tween(begin: Offset(0, -1), end: Offset(0, 0));
        break;

      case AxisDirection.left:
        _tween = Tween(begin: Offset(1, 0), end: Offset(0, 0));
        break;
    }
  }
   Animation<double> get position => listenable;
  final bool transformHitTests;
  final Widget child;
//退场（出）方向
  final AxisDirection direction;
  Tween<Offset> _tween;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Offset offset = _tween.evaluate(position);
    if (position.status == AnimationStatus.reverse) {
      switch (direction) {
        case AxisDirection.up:
          offset = Offset(offset.dx, -offset.dy);
          break;

        case AxisDirection.right:
          offset = Offset(-offset.dx, offset.dy);
          break;

        case AxisDirection.down:
          offset = Offset(-offset.dx, -offset.dy);
          break;

        case AxisDirection.left:
          offset = Offset(-offset.dx, offset.dy);
          break;
      }
    }
    return FractionalTranslation(
        translation: offset,
        transformHitTests: transformHitTests,
        child: child);
  }

 
}
